﻿namespace Home.Test
{
    using System;
    using System.Collections.Generic;
    using System.Data.Entity;
    using System.Linq;
    using System.Net;
    using System.Text;
    using System.Threading.Tasks;
    using System.Web;
    using Home.Test.Repository;

    public abstract class BaseIdentityProviderHandler : IHttpHandler
    {
        public bool IsReusable
        {
            get { return true; }
        }

        public void ProcessRequest(HttpContext context)
        {
            var type = DetermineRequestType(context);
            if (type == RequestType.Unknown)
            {
                ResponseHttpStatusCode(context, HttpStatusCode.NotFound);
                return;
            }

            try
            {
                ProcessRequestAsync(context, type).GetAwaiter().GetResult();
            }
            catch (HttpException ex)
            {
                ResponseHttpStatusCode(context, (HttpStatusCode)ex.GetHttpCode());
            }
        }

        protected abstract RequestType DetermineRequestType(HttpContext context);

        protected abstract Task ProcessRequestAsync(HttpContext context, RequestType type);

        protected static async Task<IPClient> GetClientAsync(string id)
        {
            using (var db = new IPDbContext())
            {
                return await db.Clients.FindAsync(id);
            }
        }

        protected static async Task<IPSns> GetSnsAsync(Guid id)
        {
            using (var db = new IPDbContext())
            {
                return await db.Snses.FindAsync(id);
            }
        }

        protected static async Task<IPConsent> GetConsentAsync(Guid id)
        {
            using (var db = new IPDbContext())
            {
                return await db.Consents.FindAsync(id);
            }
        }

        protected static void ResponseRedirect(HttpContext context, string location)
        {
            var response = context.Response;
            response.Clear();
            response.StatusCode = (int)HttpStatusCode.Redirect;
            response.RedirectLocation = Helper.Web.ToAbsolute(context, location);
            response.SuppressContent = true;
        }

        protected static async Task ResponseJsonAsync(HttpContext context, string json)
        {
            var response = context.Response;
            response.Clear();
            response.StatusCode = (int)HttpStatusCode.OK;
            response.ContentType = Helper.ContentType.Json;
            await response.Output.WriteLineAsync(json);
            await response.Output.FlushAsync();
        }

        protected static async Task ResponseJavaScriptAsync(HttpContext context, string json)
        {
            var response = context.Response;
            response.Clear();
            response.StatusCode = (int)HttpStatusCode.OK;
            response.ContentType = Helper.ContentType.JavaScript;
            await response.Output.WriteLineAsync(string.Format("callback({0})", json));
            await response.Output.FlushAsync();
        }

        private static void ResponseHttpStatusCode(HttpContext context, HttpStatusCode status)
        {
            var response = context.Response;
            response.Clear();
            response.StatusCode = (int)status;
            response.SuppressContent = true;
        }
    }
}
